package com.innovation.ic.cyz.base.service.cyz.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.innovation.ic.b1b.framework.util.BeanPropertiesUtil;
import com.innovation.ic.cyz.base.handler.PageHandler;
import com.innovation.ic.cyz.base.mapper.cyz.SlnMapper;
import com.innovation.ic.cyz.base.model.cyz.Sln;
import com.innovation.ic.cyz.base.model.cyz.SlnIde;
import com.innovation.ic.cyz.base.model.cyz.SlnLikeTag;
import com.innovation.ic.cyz.base.model.cyz.SlnUrl;
import com.innovation.ic.cyz.base.pojo.global.ServiceResult;
import com.innovation.ic.cyz.base.pojo.constant.SlnUrlType;
import com.innovation.ic.cyz.base.pojo.variable.cyz.SlnDetailPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.SlnListPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.SlnListResultPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.sln_search_option.SlnOptionItem;
import com.innovation.ic.cyz.base.pojo.variable.cyz.sln_search_option.SlnOptionLine;
import com.innovation.ic.cyz.base.pojo.enums.ExamineStatusEnum;
import com.innovation.ic.cyz.base.service.cyz.SlnService;
import com.innovation.ic.cyz.base.service.cyz.impl.handler.SlnSendHandler;
import com.innovation.ic.cyz.base.vo.cyz.SlnListVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 方案具体实现类
 */
@Service
@Transactional
public class SlnServiceImpl extends ServiceImpl<SlnMapper, Sln> implements SlnService {

    @Resource
    private ServiceHelper serviceHelper;

    @Resource
    private SlnSendHandler slnSendHandler;

    @Resource
    private PageHandler pageHandler;

    /**
     * 检查排序字段
     *
     * @param slnListVo
     */
    private void checkOrderByField(SlnListVo slnListVo) {
        if (slnListVo.getOrderByName() == null) slnListVo.setOrderByName("");
        if (slnListVo.getOrderByType() == null) slnListVo.setOrderByType("");

        List<String> orderByNamePreparedFields = Arrays.asList("created_at", "view_num");
        List<String> orderByTypePreparedFields = Arrays.asList("asc", "desc");

        if (orderByNamePreparedFields.stream().map(t -> t.toLowerCase()).collect(Collectors.toList())
                .contains(slnListVo.getOrderByName().toLowerCase())) {
            slnListVo.setOrderByName(slnListVo.getOrderByName().toLowerCase());
        } else {
            slnListVo.setOrderByName("");
        }

        if (orderByTypePreparedFields.stream().map(t -> t.toLowerCase()).collect(Collectors.toList())
                .contains(slnListVo.getOrderByType().toLowerCase())) {
            slnListVo.setOrderByType(slnListVo.getOrderByType().toLowerCase());
        } else {
            slnListVo.setOrderByType("");
        }
    }

    /**
     * 根据传入的条件查询方案列表
     *
     * @param slnListVo
     * @return
     */
    @Override
    public ServiceResult<SlnListResultPojo> findSlnList(SlnListVo slnListVo) {
        checkOrderByField(slnListVo); // 检查排序字段

        List<SlnListPojo> slnList = serviceHelper.getSlnMapper().findSlnList(slnListVo.getPage(), slnListVo.getSize(),
                slnListVo.getOrderByName(), slnListVo.getOrderByType(),
                slnListVo.getHotNames(),
                slnListVo.getCateNames(),
                slnListVo.getTypeDisplays(),
                slnListVo.getIdeCateNames(),
                slnListVo.getKeyWord(),
                slnListVo.getExamineStatus());
        Long slnCount = serviceHelper.getSlnMapper().findSlnCount(
                slnListVo.getHotNames(),
                slnListVo.getCateNames(),
                slnListVo.getTypeDisplays(),
                slnListVo.getIdeCateNames(),
                slnListVo.getKeyWord());

        SlnListResultPojo slnListResultPojo = new SlnListResultPojo();
        slnListResultPojo.setList(slnList);
        slnListResultPojo.setTotal(slnCount);

        ServiceResult<SlnListResultPojo> serviceResult = new ServiceResult<SlnListResultPojo>();
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(slnListResultPojo);

        return serviceResult;
    }

    /**
     * 根据id查询方案详情
     *
     * @param slnId
     * @return
     */
    @Override
    public ServiceResult<SlnDetailPojo> findSlnDetailById(Long slnId) {
        // 查询Sln
        Sln sln = serviceHelper.getSlnMapper().selectById(slnId);

        // 查询SlnUrls
        QueryWrapper<SlnUrl> qwSlnUrl = new QueryWrapper<>();
        qwSlnUrl.lambda().eq(SlnUrl::getSlnId, slnId);
        List<SlnUrl> slnUrls = serviceHelper.getSlnUrlMapper().selectList(qwSlnUrl);

        // 查询SlnLikeTags
        QueryWrapper<SlnLikeTag> qwSlnLikeTag = new QueryWrapper<>();
        qwSlnLikeTag.select(" DISTINCT tag ");
        qwSlnLikeTag.lambda().eq(SlnLikeTag::getSlnId, slnId);
        List<SlnLikeTag> slnLikeTags = serviceHelper.getSlnLikeTagMapper().selectList(qwSlnLikeTag);

        // 查询SlnIde,拼接成IdeCateName
        QueryWrapper<SlnIde> qwSlnIde = new QueryWrapper<>();
        qwSlnIde.lambda().eq(SlnIde::getSlnId, slnId);
        List<SlnIde> slnIdes = serviceHelper.getSlnIdeMapper().selectList(qwSlnIde);

        // 填写SlnDetailPojo
        SlnDetailPojo slnDetailPojo = new SlnDetailPojo();
        slnDetailPojo.setSlnId(sln.getId());
        slnDetailPojo.setGoodsCover(sln.getGoodsCover());
        slnDetailPojo.setOtherCover(slnUrls.stream().filter(t -> t.getType().equals(SlnUrlType.OtherCover))
                .map(SlnUrl::getUrl).collect(Collectors.toList()));
        slnDetailPojo.setFilePath(slnUrls.stream().filter(t -> t.getType().equals(SlnUrlType.FilePath))
                .map(SlnUrl::getUrl).collect(Collectors.toList()));
        slnDetailPojo.setTitle(sln.getTitle());
        slnDetailPojo.setDescription(sln.getDescription());
        slnDetailPojo.setCateName(sln.getCateName());
        slnDetailPojo.setDeliveryCateIdName(sln.getDeliveryCateIdName());
        slnDetailPojo.setPerformanceParameter(sln.getPerformanceParameter());
        slnDetailPojo.setApplicationScene(sln.getApplicationScene());
        slnDetailPojo.setTypeDisplay(sln.getTypeDisplay());
        slnDetailPojo.setViewNum(sln.getViewNum());
        slnDetailPojo.setLikeTags(slnLikeTags.stream().map(SlnLikeTag::getTag).collect(Collectors.toList()));

        String ideCateName = "";
        if (slnIdes != null && !slnIdes.isEmpty()) {
            ideCateName = slnIdes.stream().map(t -> t.getCateName()).collect(Collectors.joining(","));
        }
        slnDetailPojo.setIdeCateName(ideCateName);

        ServiceResult<SlnDetailPojo> serviceResult = new ServiceResult<>();
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(slnDetailPojo);

        return serviceResult;
    }

    /**
     * 将字符串转为SlnOptionItem
     *
     * @param str
     * @return
     */
    private SlnOptionItem convertStringToSlnOptionItem(String str) {
        SlnOptionItem slnOptionItem = new SlnOptionItem();
        slnOptionItem.setName(str);
        return slnOptionItem;
    }

    /**
     * 将字符串列表转为SlnOptionItem列表
     *
     * @return
     */
    private List<SlnOptionItem> convertStringListToSlnOptionItemList(List<String> stringList) {
        return stringList.stream().map(t -> {
            SlnOptionItem slnOptionItem = new SlnOptionItem();
            slnOptionItem.setName(t);
            return slnOptionItem;
        }).collect(Collectors.toList());
    }

    /**
     * 查询列表选项
     *
     * @return
     */
    @Override
    public ServiceResult<List<SlnOptionLine>> findListOptions() {
        List<SlnOptionLine> slnOptionLineList = new ArrayList<>();

        SlnOptionLine hotNameLine = new SlnOptionLine();
        hotNameLine.setLevel1Option(convertStringToSlnOptionItem("热门领域"));
        hotNameLine.setLevel2Options(convertStringListToSlnOptionItemList(Arrays.asList("物联网", "传感器", "嵌入式", "电源", "电机控制")));
        slnOptionLineList.add(hotNameLine);

        List<String> cateNames = serviceHelper.getSlnMapper().findCateNames();
        SlnOptionLine cateNameLine = new SlnOptionLine();
        cateNameLine.setLevel1Option(convertStringToSlnOptionItem("应用领域"));
        cateNameLine.setLevel2Options(convertStringListToSlnOptionItemList(cateNames));
        slnOptionLineList.add(cateNameLine);

        List<String> typeDisplays = serviceHelper.getSlnMapper().findTypeDisplays();
        SlnOptionLine typeDisplayLine = new SlnOptionLine();
        typeDisplayLine.setLevel1Option(convertStringToSlnOptionItem("方案分类"));
        typeDisplayLine.setLevel2Options(convertStringListToSlnOptionItemList(typeDisplays));
        slnOptionLineList.add(typeDisplayLine);

        List<String> ideCateNames = serviceHelper.getSlnIdeMapper().findIdeCateNames();
        SlnOptionLine ideCateNameLine = new SlnOptionLine();
        ideCateNameLine.setLevel1Option(convertStringToSlnOptionItem("开发平台"));
        ideCateNameLine.setLevel2Options(convertStringListToSlnOptionItemList(ideCateNames));
        slnOptionLineList.add(ideCateNameLine);

        ServiceResult<List<SlnOptionLine>> serviceResult = new ServiceResult<>();
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(slnOptionLineList);

        return serviceResult;
    }

    /**
     * @Description: 添加比一比方案数据
     * param null
     * @return: null
     * @Author: Mr.myq
     * @Date: 2022/9/1614:21
     */
    @Override
    @Transactional
    public ServiceResult addSinInfo(Sln sin) {
        sin.setCreatedAt(new Date());
        sin.setExamineStatus(0);
        sin.setStatusDisplay("待审核");
        Assert.isTrue(this.baseMapper.insert(sin) > 0 ,"添加BIB方案数据异常");
        return ServiceResult.ok("添加BIB方案数据成功");
    }

    /**
     * @Description: 添加其他封面数据
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/1914:44
     */
    @Override
    public ServiceResult addSinUrls(List<SlnUrl> sinUrls) {
        Assert.isTrue(serviceHelper.getSlnUrlMapper().insertBatchSomeColumn(sinUrls) > 0,"批量添加方案其他封面数据异常");
        return ServiceResult.ok("批量添加方案其他封面数据ok");
    }


    @Override
    public ServiceResult updateSinInfo(Sln sin) {
        UpdateWrapper<Sln> wrapper = new UpdateWrapper<>();
        wrapper.set("source",sin.getSource());
        wrapper.set("sln_id",sin.getSlnId());
        Assert.isTrue(this.baseMapper.update(sin,wrapper) > 0 ,"更新方案数据异常");
        return ServiceResult.ok("添加BIB方案数据成功");
    }

    @Override
    public ServiceResult updateSinUrls(List<SlnUrl> sinUrls) {
        sinUrls.forEach(e->{
            Assert.isTrue(serviceHelper.getSlnUrlMapper().updateById(e) > 0,"更新方案其他封面数据异常");
        });
        return ServiceResult.ok("更新BIB方案其他封面数据成功");
    }


    /**
     * @Description: 删除方案所有数据
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2117:23
     */
    @Override
    public ServiceResult deleteSlnInfo(Sln sln) {
        LambdaQueryWrapper<Sln> slnLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnLambdaQueryWrapper.eq(Sln::getSlnId,sln.getSlnId());
        slnLambdaQueryWrapper.eq(Sln::getSource,sln.getSource());
        Sln slnQuery = this.baseMapper.selectOne(slnLambdaQueryWrapper);

        LambdaQueryWrapper<SlnUrl> urlLambdaQueryWrapper = new LambdaQueryWrapper<>();
        urlLambdaQueryWrapper.eq(SlnUrl::getSlnId,slnQuery.getId());
        serviceHelper.getSlnUrlMapper().delete(urlLambdaQueryWrapper);

        this.baseMapper.deleteById(slnQuery.getId());

        return ServiceResult.ok("删除方案数据成功");
    }


    /**
     * @Description: 查询方案信息
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/229:38
     * @return
     */
    @Override
    public ServiceResult<PageInfo<SlnListPojo>> page(int pageNo, int pageSize, SlnListVo slnListVo) {
        PageHelper.startPage(pageNo,pageSize);
        List<SlnListPojo> page = serviceHelper.getSlnMapper().page(
                slnListVo.getHotNames(),
                slnListVo.getCateNames(),
                slnListVo.getTypeDisplays(),
                slnListVo.getIdeCateNames(),
                slnListVo.getKeyWord(),
                slnListVo.getExamineStatus());
        return ServiceResult.ok(new PageInfo<>(page),"ok");
    }

    /**
     * @Description: 热门领域列表
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2210:38
     */
    @Override
    public ServiceResult<List<SlnLikeTag>> hotNameList() {
        return ServiceResult.ok(serviceHelper.getSlnLikeTagMapper().selectList(new QueryWrapper<>()),"获取热门领域ok");
    }


    /**
     * @Description: 开放平台
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2210:46
     */
    @Override
    public ServiceResult<List<SlnIde>> slnIdeList() {
        return ServiceResult.ok(serviceHelper.getSlnIdeMapper().selectList(new QueryWrapper<>()),"获取开放平台列表ok");
    }


    /**
     * @Description: 更新方案
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2211:01
     */
    @Override
    @Transactional
    public ServiceResult update(Sln sln) {
        Sln res = this.baseMapper.selectById(sln.getId());

        LambdaQueryWrapper<SlnUrl> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SlnUrl::getSlnId,res.getSlnId());
        List<SlnUrl> slnUrls = serviceHelper.getSlnUrlMapper().selectList(queryWrapper);

        Assert.isTrue(this.baseMapper.updateById(sln) > 0,"更新方案失败");
        slnSendHandler.sendRemoteUpdateMsg(res,slnUrls.stream().map(SlnUrl::getUrl).collect(Collectors.toList()));
        return ServiceResult.ok("更新方案ok");
    }

    /**
     * @Description: 删除方案
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2211:07
     */
    @Override
    @Transactional
    public ServiceResult delete(Long id) {
        Sln res = this.baseMapper.selectById(id);
        Assert.isTrue(this.baseMapper.deleteById(id)>0,"删除数据方案异常");

        LambdaQueryWrapper<SlnUrl> slnUrlLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnUrlLambdaQueryWrapper.eq(SlnUrl::getSlnId , id);
        Assert.isTrue(serviceHelper.getSlnUrlMapper().delete(slnUrlLambdaQueryWrapper) > 0,"删除其他封面数据异常");

        LambdaQueryWrapper<SlnIde> slnIdeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnIdeLambdaQueryWrapper.eq(SlnIde::getSlnId , id);
        serviceHelper.getSlnIdeMapper().delete(slnIdeLambdaQueryWrapper);

        LambdaQueryWrapper<SlnLikeTag> slnTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnTagLambdaQueryWrapper.eq(SlnLikeTag::getSlnId , id);
        serviceHelper.getSlnLikeTagMapper().delete(slnTagLambdaQueryWrapper);
        //传输 业务方对应的slnId
        slnSendHandler.sendRemoteDeleteMsg(res.getSlnId().toString());

        return ServiceResult.ok("删除成功");
    }

    /**
     * @Description: BIB数据
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/9/2313:42
     */
    @Override
    public ServiceResult<PageInfo<SlnListPojo>> b1bPage(int pageNo, int pageSize, String startTime) {
        PageHelper.startPage(pageNo, pageSize);

        LambdaQueryWrapper<Sln> slnLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnLambdaQueryWrapper.eq(Sln::getExamineStatus, ExamineStatusEnum.EXAMINATION_PASSED.getKey());
        slnLambdaQueryWrapper.orderByDesc(Sln::getCreatedAt);
        slnLambdaQueryWrapper.ge(Sln::getCreatedAt,startTime);
        List<Sln> slns = this.baseMapper.selectList(slnLambdaQueryWrapper);
        List<Long> slnIds = slns.stream().map(Sln::getId).collect(Collectors.toList());
        //转换后的分页
        PageInfo<SlnListPojo> slnListPojoPageInfo = pageHandler.convertPage(slns, SlnListPojo.class);

        if(CollectionUtils.isEmpty(slnIds))
            return ServiceResult.ok(slnListPojoPageInfo,"ok");

        LambdaQueryWrapper<SlnUrl> slnUrlLambdaQueryWrapper = new LambdaQueryWrapper<>();
        slnUrlLambdaQueryWrapper.in(SlnUrl::getSlnId,slnIds);
        slnUrlLambdaQueryWrapper.eq(SlnUrl::getType,1);
        List<SlnUrl> slnUrls = serviceHelper.getSlnUrlMapper().selectList(slnUrlLambdaQueryWrapper);
        // list -> map
        Map<Long, List<SlnUrl>> collect = slnUrls.stream().collect(Collectors.groupingBy(SlnUrl::getSlnId));

        slnListPojoPageInfo.getList().forEach(e->{
            if(collect.containsKey(e.getId())) {
                List<SlnUrl> val = collect.get(e.getId());
                List<String> stringUrls = val.stream().map(SlnUrl::getUrl).collect(Collectors.toList());
                String join = String.join(",", stringUrls);
                e.setGoodsOtherCover(join);
            }
        });

        return ServiceResult.ok(slnListPojoPageInfo,"ok");
    }
}

